﻿using System;
using System.Windows.Input;
using System.Diagnostics;

namespace ParallelGrep
{
    /// <summary>
    /// リレイコマンドクラス
    /// </summary>
    public class RelayCommand : ICommand
    {
        #region Fields
        readonly Action<object> m_execute;
        readonly Predicate<object> m_canExecute;
        #endregion // Fields

        #region Constructors
        /// <summary>
        /// 指定したアクションで新しい<see cref="RelayCommand"/>クラスを生成します。
        /// </summary>
        /// <param name="execute">アクション</param>
        public RelayCommand(Action<object> execute)
            : this(execute, null)
        {
        }
        /// <summary>
        /// 指定したアクション、実行判定で新しい<see cref="RelayCommand"/>クラスを生成します。
        /// </summary>
        /// <param name="execute">アクション</param>
        /// <param name="canExecute">実行判定</param>
        public RelayCommand(Action<object> execute, Predicate<object> canExecute)
        {
            if (execute == null)
            {
                throw new ArgumentNullException("execute");
            }

            m_execute = execute;
            m_canExecute = canExecute;
        }
        #endregion // Constructors

        #region ICommand Members

        #region CanExecute
        /// <summary>
        /// 指定したパラメータで、実行判定を行います。
        /// </summary>
        /// <param name="parameter">実行判定</param>
        /// <returns>trueの場合は実行可能、falseの場合は実行不可</returns>
        [DebuggerStepThrough]
        public bool CanExecute(object parameter)
        {
            return m_canExecute == null ? true : m_canExecute(parameter);
        }
        #endregion

        #region CanExecuteChanged
        /// <summary>
        /// 実行判定ハンドラを追加または削除します。
        /// </summary>
        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
        #endregion

        #region Execute
        /// <summary>
        /// 指定したパラメータで実行します。
        /// </summary>
        /// <param name="parameter">パラメータ</param>
        public void Execute(object parameter)
        {
            m_execute(parameter);
        }
        #endregion

        #endregion // ICommand Members
    }
}
